package com.heima.comment.service.impl;

import com.heima.comment.service.CommentHotService;
import com.heima.comment.service.CommentService;
import com.heima.common.exception.CustException;
import com.heima.feigns.UserFeign;
import com.heima.model.comment.dtos.CommentDto;
import com.heima.model.comment.dtos.CommentLikeDto;
import com.heima.model.comment.dtos.CommentSaveDto;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentLike;
import com.heima.model.comment.vos.ApCommentVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.threadlocal.AppThreadLocalUtils;
import com.heima.model.user.pojos.ApUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


@Service
@Slf4j
public class CommentServiceImpl implements CommentService {

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    UserFeign userFeign;

    @Autowired
    CommentHotService commentHotService;

    @Override
    public ResponseResult saveComment(CommentSaveDto dto) {
        // 检验参数
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            CustException.cust(AppHttpCodeEnum.NEED_LOGIN);
        }

        ResponseResult<ApUser> userResponseResult = userFeign.findUserById(user.getId());

        if (userResponseResult.getCode().intValue() != 0 || userResponseResult.getData() == null) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "获取登录信息失败");
        }
        user = userResponseResult.getData();
        ApComment apComment = new ApComment();
        apComment.setAuthorId(user.getId());
        apComment.setAuthorName(user.getName());
        apComment.setEntryId(dto.getArticleId());
        apComment.setType((short) 0);
        apComment.setContent(dto.getContent());
        apComment.setImage(user.getImage());
        apComment.setLikes(0);
        apComment.setReply(0);
        apComment.setFlag((short) 0);
        apComment.setCreatedTime(new Date());
        apComment.setUpdatedTime(new Date());
        mongoTemplate.save(apComment);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult like(CommentLikeDto dto) {
        // 校验参数
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            CustException.cust(AppHttpCodeEnum.NEED_LOGIN);
        }
        // 获取是那个评论
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        if (apComment == null) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "获取评论失败");
        }

        // 获取点赞实体行为
        Query query = Query.query(Criteria.where("authorId").is(user.getId()).and("commentId").is(dto.getCommentId()));

        ApCommentLike commentLike = mongoTemplate.findOne(query, ApCommentLike.class);
        if (commentLike != null && commentLike.getOperation().intValue() == 0) {
            CustException.cust(AppHttpCodeEnum.DATA_EXIST,"不可以点赞两次奥，你试试点三次233");
        }
        if (dto.getOperation().intValue() == 0) {
            // 点赞    增加评论点赞数   生成点赞行为实体
            apComment.setLikes(apComment.getLikes()+1);
            mongoTemplate.save(apComment);
            if (apComment.getLikes() >= 5 && apComment.getFlag().shortValue() == 0) {
                this.commentHotService.hotCommentExecutor(apComment);
            }

            commentLike = new ApCommentLike();
            commentLike.setAuthorId(user.getId());
            commentLike.setCommentId(dto.getCommentId());
            commentLike.setOperation((short) 0);
            mongoTemplate.save(commentLike);
        } else {
            // 取消点赞 减少评论点赞数  删除点赞行为实体
            apComment.setLikes(apComment.getLikes() == 0 ? 0 : apComment.getLikes() - 1);
            mongoTemplate.save(apComment);

            mongoTemplate.remove(query, ApCommentLike.class);
        }
        Map<String, Object> map = new HashMap();
        map.put("likes", apComment.getLikes());
        return ResponseResult.okResult(map);
    }

//    @Override
//    public ResponseResult findByArticleId(CommentDto dto) {
//        // 检验参数
//        if (dto == null || dto.getArticleId() == null) {
//            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
//        }
//
//        if (dto.getMinDate() == null) {
//            dto.setMinDate(new Date());
//        }
//
//        Integer size = dto.getSize();
//        if (dto.getSize() == null) {
//            size = 10;
//        }
//
//        // 查询评论列表
//        List<ApComment> commentList = mongoTemplate.find(Query.query(Criteria.where("entryId").is(dto.getArticleId())
//                .and("createdTime").lt(dto.getMinDate()))
//                .limit(size)
//                .with(Sort.by(Sort.Direction.DESC, "createdTime")), ApComment.class);
//
//        // 判断是否登录  展示不同的界面
//        ApUser user = AppThreadLocalUtils.getUser();
//        if (user == null) {
//          return   ResponseResult.okResult(commentList);
//        }
//
//        // 获取评论列表的所有ID，根据ID查询点赞行为列表
//        List<String> ids = commentList.stream().map(ApComment::getId).collect(Collectors.toList());
//        List<ApCommentLike> commentLikeList = mongoTemplate.find(Query.query(Criteria.where("authorId").is(user.getId())
//                .and("commentId").in(ids)), ApCommentLike.class);
//        // 遍历列表 封装实体vo
//        List<ApCommentVo> apCommentVoList = new ArrayList<>();
//
//        if (commentList != null && commentList.size() > 0 && commentLikeList != null && commentLikeList.size() > 0) {
//
//            for (ApComment apComment : commentList) {
//                ApCommentVo apCommentVo = new ApCommentVo();
//                BeanUtils.copyProperties(apComment,apCommentVo);
//                String commentId = apComment.getId();
//                for (ApCommentLike apCommentLike : commentLikeList) {
//                    if (apCommentLike.getCommentId() == commentId) {
//                        apCommentVo.setOperation((short) 0);
//                    }
//                }
//                apCommentVoList.add(apCommentVo);
//            }
//            return ResponseResult.okResult(apCommentVoList);
//        }
//        // 返回
//        return ResponseResult.okResult(commentList);
//    }


    @Override
    public ResponseResult findByArticleId(CommentDto dto) {
        if (dto==null||dto.getArticleId()==null) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID, "建议前端主动辞职");
        }
        if (dto.getSize()==null) {
            dto.setSize(10);
        }
        if (dto.getMinDate()==null) {
            dto.setMinDate(new Date());
        }

        // 如果是首页先来几条热点数据
        List<ApComment> apComments = new ArrayList<>();

        if (dto.getIndex().intValue() == 1) {
            Query query = Query.query(Criteria.where("entryId").is(dto.getArticleId())
                    .and("flag").is(1))
                    .with(Sort.by(Sort.Direction.DESC, "likes"));
            apComments = mongoTemplate.find(query, ApComment.class);
            if (apComments.size() > 0) {
                if (dto.getSize() > apComments.size()) {
                    List<ApComment> noHotCommentList = mongoTemplate.find(Query.query(Criteria.where("entryId").is(dto.getArticleId())
                            .and("flag").is(0)
                            .and("createdTime").lt(dto.getMinDate()))
                            .limit(dto.getSize() - apComments.size())
                            .with(Sort.by(Sort.Direction.DESC, "likes")), ApComment.class);
                    apComments.addAll(noHotCommentList);
                }

            } else {
                List<ApComment> noHotCommentList = mongoTemplate.find(Query.query(Criteria.where("entryId").is(dto.getArticleId())
                        .and("flag").is(0)
                        .and("createdTime").lt(dto.getMinDate()))
                        .limit(dto.getSize())
                        .with(Sort.by(Sort.Direction.DESC, "likes")), ApComment.class);
                apComments = noHotCommentList;
            }
        } else {
            List<ApComment> noHotCommentList = mongoTemplate.find(Query.query(Criteria.where("entryId").is(dto.getArticleId())
                    .and("flag").is(0)
                    .and("createdTime").lt(dto.getMinDate()))
                    .limit(dto.getSize())
                    .with(Sort.by(Sort.Direction.DESC, "likes")), ApComment.class);
            apComments = noHotCommentList;
        }
        ApUser user = AppThreadLocalUtils.getUser();
        List<ApCommentVo> list = new ArrayList<>();
        if (user == null) {
            return ResponseResult.okResult(apComments);
        }
        List<String> commentsIds = apComments.stream().map(ApComment::getId).collect(Collectors.toList());
        List<ApCommentLike> commentLikeList = mongoTemplate.find(Query.query(Criteria.where("authorId").is(user.getId())
                .and("commentId").in(commentsIds)), ApCommentLike.class);
        for (ApComment apComment : apComments) {
            ApCommentVo apCommentVo = new ApCommentVo();
            BeanUtils.copyProperties(apComment, apCommentVo);
            for (ApCommentLike apCommentLike : commentLikeList) {
                if (apCommentLike.getCommentId().equals(apComment.getId())) {
                    apCommentVo.setOperation((short) 0);
                }
            }
            list.add(apCommentVo);
        }
        return ResponseResult.okResult(list);

    }
}
